/**
 * Copyright (C) 2021-2022 maminjie <canpool@163.com>
 * SPDX-License-Identifier: LGPL-2.1
 * Powered by Qt-Advanced-Docking-System
**/

#pragma once

#include "qads_global.h"

#include <QWidget>

QT_BEGIN_NAMESPACE
class QToolBar;
class QXmlStreamWriter;
QT_END_NAMESPACE

QADS_BEGIN_NAMESPACE

class DockWidgetPrivate;
class DockTab;
class DockManager;
class DockPannel;
class DockContainer;
class DockContainerPrivate;
class DockFloatingWidget;

class QADS_EXPORT DockWidget : public QWidget
{
    Q_OBJECT
public:
    enum State { StateDocked, StateFloating };
    enum InsertMode { AutoScrollArea, ForceScrollArea, ForceNoScrollArea };
    enum MinimumSizeHintMode { MinimumSizeHintFromDockWidget, MinimumSizeHintFromContent };
    enum ToggleViewActionMode { ActionModeToggle, ActionModeShow };

public:
    DockWidget(const QString &uniqueId, QWidget *parent = nullptr);
    ~DockWidget() override;

    void setWidget(QWidget *widget, InsertMode mode = AutoScrollArea);
    QWidget *widget() const;
    QWidget *takeWidget();

    enum DockWidgetFeature {
        DockWidgetClosable = 0x001,
        DockWidgetMovable = 0x002,
        DockWidgetFloatable = 0x004,
        DockWidgetDeleteOnClose = 0x008,
        CustomCloseHandling = 0x010,
        DockWidgetFocusable = 0x020, ///< if this is enabled, a dock widget can get focus highlighting
        DockWidgetForceCloseWithArea = 0x040, ///< dock widget will be closed when the dock pannel hosting it is closed
        NoTab = 0x080, ///< dock widget tab will never be shown if this flag is set
        DeleteContentOnClose = 0x100, ///< deletes only the contained widget on close,
        ///< keeping the dock widget intact and in place.
        ///< Attempts to rebuild the contents widget on show if there is a widget factory set.
        DefaultDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable | DockWidgetFocusable,
        AllDockWidgetFeatures = DefaultDockWidgetFeatures | DockWidgetDeleteOnClose | CustomCloseHandling,
        DockWidgetAlwaysCloseAndDelete = DockWidgetForceCloseWithArea | DockWidgetDeleteOnClose,
        NoDockWidgetFeatures = 0x000
    };
    Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature)

    DockWidgetFeatures features() const;
    void setFeatures(DockWidgetFeatures features);
    void setFeature(DockWidgetFeature flag, bool on);

    DockManager *dockManager() const;
    DockContainer *dockContainer() const;
    DockPannel *dockPannel() const;
    DockFloatingWidget *dockFloatingWidget() const;

    DockTab *tab() const;

    QAction *toggleViewAction() const;
    void setToggleViewActionMode(ToggleViewActionMode mode);

    void setMinimumSizeHintMode(MinimumSizeHintMode mode);

    QIcon icon() const;
    void setIcon(const QIcon &icon);

    QToolBar *toolBar() const;
    void setToolBar(QToolBar *toolBar);

    Qt::ToolButtonStyle toolBarButtonStyle(State state) const;
    void setToolBarButtonStyle(Qt::ToolButtonStyle style, State state);

    QSize toolBarIconSize(State state) const;
    void setToolBarIconSize(const QSize &iconSize, State state);

    virtual QList<QAction *> titleBarActions() const;
    void setTitleBarActions(QList<QAction *> actions);

#ifndef QT_NO_TOOLTIP
    void setTabToolTip(const QString &text);
#endif

    bool isCentralWidget() const;

    bool isCurrentTab() const;
    void setAsCurrentTab();

    bool isFloating() const;
    void setFloating();

    bool isInFloatingContainer() const;
    bool isClosed() const;
    bool isTabbed() const;
    bool isFullScreen() const;

    void toggleView(bool open = true);

    QSize minimumSizeHint() const override;

    using FactoryFunc = std::function<QWidget*(QWidget*)>;
    void setWidgetFactory(FactoryFunc createWidget, InsertMode insertMode = AutoScrollArea);

public:
    void showFullScreen();
    void showNormal();

    void raise();

    void deleteDockWidget();
    void closeDockWidget();

signals:
    void viewToggled(bool open);
    void closed();
    void titleChanged(const QString &title);
    void topLevelChanged(bool topLevel);
    void closeRequested();
    void visibilityChanged(bool visible);
    void featuresChanged(DockWidgetFeatures features);

protected:
    void setDockManager(DockManager *dockManager);
    void setDockPannel(DockPannel *pannel);

    void setToggleViewActionChecked(bool checked);

    void saveState(QXmlStreamWriter &stream) const;
    void setClosedState(bool closed);

    void flagAsUnassigned();

    static void emitTopLevelEventForWidget(DockWidget *topLevelDockWidget, bool floating);
    void emitTopLevelChanged(bool floating);

    void toggleViewInternal(bool open);
    bool closeDockWidgetInternal(bool forceClose = false);

protected:
    bool event(QEvent *event) override;

private:
    DockWidgetPrivate *d;
    friend class DockWidgetPrivate;
    friend class DockContainer;
    friend class DockPannel;
    friend class DockFloatingWidget;
    friend class DockManager;
    friend class DockManagerPrivate;
    friend class DockContainerPrivate;
    friend class DockTabBar;
    friend class DockTab;
    friend class DockTabPrivate;
    friend class DockTitleBarPrivate;
}; // class DockWidget

QADS_END_NAMESPACE

Q_DECLARE_OPERATORS_FOR_FLAGS(QAds::DockWidget::DockWidgetFeatures)
